import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature
import groovy.sql.Sql;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils
import org.junit.jupiter.api.Test
import wsd.sys.SST;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import java.util.Base64

def execute(params, dldt) {
    long s1 = System.currentTimeMillis();
    Map resultMap = new HashMap();
    List<String> msgList = new ArrayList<>();//错误信息
    def conn
    try {
        if (!params.containsKey("phone") || params.get("phone").toString().trim().equals("")) {
            msgList.add("手机号不可为空.");
        }
        if (msgList.size() > 0) {
            resultMap.put("status", "0");
            resultMap.put("msg", "获取单点登录地址失败：" + String.join(" ", msgList));
            resultMap.put("url", "");
            return resultMap;
        }
        def qysParams = getQYS_API()
        if (qysParams.status.equals("0")) {
            resultMap.put("status", "0");
            resultMap.put("msg", "获取单点登录地址失败：" + qysParams.msg);
            resultMap.put("url", "");
            return resultMap;
        }
        //秘钥(需要使用长度为16、24或32的字节数组作为AES算法的密钥，否则就会遇到java.security.InvalidKeyException异常)
        String key = qysParams.data.aesSecret;
//        AES.AESTest();
        String encryptPhone = params.get("phone");//手机号加密字符串
        // 解密
        byte[] decrypted = Base64.getDecoder().decode(encryptPhone);
        key = "20240829bainuo!@";
        AESUtil.main();
        def phone = AESUtil.decrypt(decrypted, key)//手机号解密
        if (phone.equals("解密失败")) {
            resultMap.put("status", "0");
            resultMap.put("msg", "获取单点登录地址失败：手机号解密失败.");
            resultMap.put("url", "");
            return resultMap;
        }
        conn = groovy.sql.Sql.newInstance(dldt.hqcon(2))
        String sql = '''select sm_user.user_code,sm_user.user_name,bd_psndoc.mobile 
        from sm_user left join bd_psndoc on sm_user.pk_psndoc =bd_psndoc.pk_psndoc 
        where bd_psndoc.mobile =? '''
        def it = conn.firstRow(sql, [phone])
        if (it == null) {
            resultMap.put("status", "0");
            resultMap.put("msg", "未查询到该手机号的用户.");
            resultMap.put("url", "");
            return resultMap;
        }
        qysParams.data.put("phone", it.user_code);
        def urlStr = PostThirdPartyAccessTokenTest.getUrl("首页", qysParams.data);
        resultMap.put("status", "1");
        resultMap.put("msg", "获取单点登录地址成功");
        resultMap.put("url", urlStr);
    } catch (Exception e) {
        e.printStackTrace()
        resultMap.put("status", "0");
        resultMap.put("msg", "获取单点登录地址失败：" + e.getMessage());
        resultMap.put("url", "");
    }finally {
        if (conn != null) {
            conn.close()
        }
    }
    long s2 = System.currentTimeMillis();
    println("耗时=" + (s2 - s1));
    return resultMap;
}

/**
 * @auther ：王春山
 * @Description ：bip信息配置查询
 * @param ：参数
 * @return ：Map
 * @date ：2024-09-06
 */
def getQYS_API() {
    def conn = null
    try {
        conn = Sql.newInstance(SST.hqcon(1))
        def result = conn.firstRow(" select * from [BN_bipCon] ")
        if (result == null) {
            return ["status": "0", "msg": "获取失败，无配置信息"]
        }
        return ["status": "1", "msg": "获取成功", "data": result]
    } catch (Exception e) {
        e.printStackTrace()
        return ["status": "0", "msg": "获取失败，无配置信息"]
    } finally {
        if (conn != null) {
            conn.close()
        }
    }
}

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

public class AESUtil {

    // AES密钥算法
    public static byte[] encrypt(String plaintext, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(plaintext.getBytes());
    }

    public static String decrypt(byte[] ciphertext, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(ciphertext);
        return new String(decryptedBytes);
    }

    public static void main(String[] args) {
        try {
            String plaintext = "18561537045";
            String key = "20240829bainuo!@";

            // 加密
            byte[] encrypted = encrypt(plaintext, key);
            String encryptedText = Base64.getEncoder().encodeToString(encrypted);
            System.out.println("加密后: " + encryptedText);

            // 解密
            byte[] decrypted = Base64.getDecoder().decode(encryptedText);
            String decryptedText = decrypt(decrypted, key);
            System.out.println("解密后: " + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 创建人：宁方华
 创建时间：2024-08-29
 类作用： Java使用AES加密算法进行加密解密
 * */
public class AES {
    /**
     * AES算法加密
     * @Param:text原文
     * @Param:key密钥
     * */
    public static String AESEncrypt(String text, String key) throws Exception {
        // 创建AES加密算法实例(根据传入指定的秘钥进行加密)
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");

        // 初始化为加密模式，并将密钥注入到算法中
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        // 将传入的文本加密
        byte[] encrypted = cipher.doFinal(text.getBytes());

        //生成密文
        // 将密文进行Base64编码，方便传输
        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * AES算法解密
     * @Param:base64Encrypted密文
     * @Param:key密钥
     * */
    public static String AESDecrypt(String base64Encrypted, String key) {
        try {
            // 创建AES解密算法实例
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");

            // 初始化为解密模式，并将密钥注入到算法中
            cipher.init(Cipher.DECRYPT_MODE, keySpec);

            // 将Base64编码的密文解码
            byte[] encrypted = Base64.getDecoder().decode(base64Encrypted);

            // 解密
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            return "解密失败";
        }
    }


}


import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLConnection;
import nccloud.security.impl.SignatureTookKit;

public class PostThirdPartyAccessTokenTest {
    /**
     * 获取登录地址URL
     *
     * @param cType 获取url类型：首页、审批详情、单据详情
     */
    public static String getUrl(String cType, Map<String, String> dataMap) throws Exception {
        String urlStr = "";
        String dsname = dataMap.get("dsname");//数据源的编码，本地开发为design
        String usercode = dataMap.get("phone");//用户的编码，需要用户可以正常登陆
        String client_id = dataMap.get("client_id");//第三方系统id，
        String client_security = dataMap.get("client_security");//第三方秘钥
        String busicentercode = dataMap.get("busicentercode");//账套编码，本地开发时为develop
        String url = dataMap.get("urlToken");
        println "urlToken"
        println(url)
        String security = genKey(usercode, usercode + client_security + (System.currentTimeMillis() + "").substring(0, 6));
        String write = "type=type_security&dsname=" + dsname + "&usercode=" + usercode + "&client_id=" + client_id + "&security=" + security + "&busicentercode=" + busicentercode;
        write = write.replaceAll("\\+", "%2B");//避免出现特殊符号问题。
        //获取token
        String token = getToken(url, write);
        if ("".equals(token)) {
            urlStr = "获取token失败";
            return urlStr;
        }
        if (cType.equals("首页")) {
            urlStr = getBaseRedirectUrl(token, dataMap);
        }
        return urlStr;
    }

    /**
     * 单点登录到首页：http://10.1.1.226:10088/nccloud
     *
     * @param token 单点登录获取到的token
     */
    private static String getBaseRedirectUrl(String token, Map<String, String> dataMap) {
        //单点成功后的跳转路径
        String redirect_uri = dataMap.get("urlBIP") + "/nccloud";
        //单点登陆时的全路径，可以直接粘贴到浏览器进行访问。
        String fullUrl = dataMap.get("urlBIP") + "/nccloud/resources/uap/rbac/thirdpartylogin/main/index.html?accesstoken=" + token + "&redirect_uri=" + redirect_uri;
        println"单点登陆时的全路径"
        println(fullUrl)
        return fullUrl;
    }

    /**调用接口获取token
     *
     * @param url 要调用的接口
     * @param write 需要写出的数据
     * @return token值
     * */
    private static String getToken(String url, String write) {


        OutputStream outStream = null;
        DataOutputStream dataOutput = null;
        InputStream inStream = null;
        String ret = "";
        try {
            URL preUrl = new URL(url);
            URLConnection con = preUrl.openConnection();

            //设置为true，后面可以调用getOutputStream并传输数据
            con.setDoOutput(true);
            //不使用http缓存
            con.setUseCaches(false);
            //设置http请求头
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setRequestProperty("Content-Length", "10000");

            HttpURLConnection httpCon = (HttpURLConnection) con;
            //这里使用post方式调用接口
            httpCon.setRequestMethod("POST");
            //获取输出流
            outStream = httpCon.getOutputStream();
            dataOutput = new DataOutputStream(outStream);
            //接口需要的参数作为字节序列写入输出流
            dataOutput.writeBytes(write);
            dataOutput.flush();
            //获取输入流
            inStream = httpCon.getInputStream();
            //读取服务返回的数据
            int ch;
            while ((ch = inStream.read()) != -1) {
                ret += String.valueOf((char) ch);
            }

        } catch (Exception e) {
            e.printStackTrace();
            println("获取BIPtoken失败！");
        } finally {
            //关闭服务输入流和输出流
            if (dataOutput != null) {
                try {
                    dataOutput.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        //返回读取的token
        return ret;
    }

    private static String genKey(String userid, String key) throws Exception {
        //return new Base64().encodeToString(SignatureTookKit.digestSign(userid.getBytes(), key.getBytes()));
        // 计算签名
        byte[] signedData = SignatureTookKit.digestSign(userid.getBytes(), key.getBytes());
        // 使用 Java 8 的 Base64 编码
        return Base64.getEncoder().encodeToString(signedData);
    }

    private static String encodeURI(String str) {
        try {
            return URLEncoder.encode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }
}